|
|||||||||||||||||||
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover | |||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
Dispatcher.java | 100% | 90.9% | 80% | 90.9% |
|
1 |
/*
|
|
2 |
* $Id: Dispatcher.java,v 1.1 2004/12/15 14:18:10 patforna Exp $
|
|
3 |
*
|
|
4 |
* Copyright (c) 2004 Patric Fornasier, Pawel Kowalski
|
|
5 |
* Berne University of Applied Sciences
|
|
6 |
* School of Engineering and Information Technology
|
|
7 |
* All rights reserved.
|
|
8 |
*/
|
|
9 |
package bexee.core;
|
|
10 |
|
|
11 |
import org.apache.commons.logging.Log;
|
|
12 |
import org.apache.commons.logging.LogFactory;
|
|
13 |
|
|
14 |
import bexee.dao.BPELProcessDAO;
|
|
15 |
import bexee.dao.DAOException;
|
|
16 |
import bexee.dao.DAOFactory;
|
|
17 |
import bexee.model.process.BPELProcess;
|
|
18 |
|
|
19 |
/**
|
|
20 |
* This class is used to lookup or create a <code>ProcessInstance</code> given
|
|
21 |
* an inbound <code>BexeeMessage</code> and dispatch the message to the
|
|
22 |
* {@link bexee.core.ProcessController}either synchronously or asynchronoulsy.
|
|
23 |
* <p>
|
|
24 |
* To do this, create the object and then use its {@link #dispatch()}method.
|
|
25 |
* <p>
|
|
26 |
* When the <code>Dispatcher</code> kicks off the
|
|
27 |
* <code>ProcessController</code> it will know, whether a synchronous or
|
|
28 |
* asynchronous BPEL process is to be started. Depending on that it will either
|
|
29 |
* return right away after starting the process for an asynchronous BPEL process
|
|
30 |
* or it will wait until the result is available for a synchronous BPEL process.
|
|
31 |
* <p>
|
|
32 |
* Either way the <code>ProcessController</code>'s
|
|
33 |
* <code>processMessage()</code> method is started in a new Thread, but in
|
|
34 |
* case of a synchronous BPEL process the <code>Dispatcher</code> will wait
|
|
35 |
* until the result is available. This happens by obtaining a lock on the
|
|
36 |
* <code>ProcessContext</code>, which will notify the <code>Dispatcher</code>
|
|
37 |
* when the result is available.
|
|
38 |
*
|
|
39 |
* @version $Revision: 1.1 $, $Date: 2004/12/15 14:18:10 $
|
|
40 |
* @author Patric Fornasier
|
|
41 |
* @author Pawel Kowalski
|
|
42 |
*/
|
|
43 |
public class Dispatcher extends Thread { |
|
44 |
|
|
45 |
/**
|
|
46 |
* Result when processing an asynchronous result. This might change in
|
|
47 |
* future versions.
|
|
48 |
*/
|
|
49 |
public static final String ASYNC_RESULT = "Processing request..."; |
|
50 |
|
|
51 |
protected ProcessController controller;
|
|
52 |
|
|
53 |
protected ProcessInstance instance;
|
|
54 |
|
|
55 |
protected BexeeMessage message;
|
|
56 |
|
|
57 |
private static Log log = LogFactory.getLog(Dispatcher.class); |
|
58 |
|
|
59 |
/**
|
|
60 |
* Creates a new <code>Dispatcher</code> object.
|
|
61 |
*
|
|
62 |
* @param message
|
|
63 |
* the incoming message
|
|
64 |
*/
|
|
65 | 14 |
public Dispatcher(BexeeMessage message) {
|
66 | 14 |
this.message = message;
|
67 |
|
|
68 |
// get BPELProcess and ProcessContext for incoming message
|
|
69 | 14 |
BPELProcess process = getBPELProcess(message); |
70 | 14 |
ProcessContext ctx = getProcessContext(message); |
71 |
|
|
72 |
// create instance from BPELProcess and ProcessContext
|
|
73 | 14 |
instance = new ProcessInstance(process, ctx);
|
74 |
|
|
75 |
// create process controller
|
|
76 | 14 |
controller = ProcessControllerFactory.createProcessController(); |
77 |
} |
|
78 |
|
|
79 |
/**
|
|
80 |
* Calls the {@link ProcessController}s
|
|
81 |
* {@link ProcessController#processMessage(ProcessInstance, BexeeMessage)}
|
|
82 |
* method either synchronously or asynchronously.
|
|
83 |
* <p>
|
|
84 |
* Note that this method may take minutes or hours for long-running
|
|
85 |
* synchronous processes.
|
|
86 |
*
|
|
87 |
* @return the result
|
|
88 |
* @throws DispatcherException
|
|
89 |
* If something went wrong dispatching the message. This can
|
|
90 |
* happen for example if the <code>BPELProcess</code> or the
|
|
91 |
* <code>ProcessContext</code> can't be found or created or if
|
|
92 |
* something went wrong processing the message in the
|
|
93 |
* <code>ProcessController</code>.
|
|
94 |
*/
|
|
95 | 14 |
public Object dispatch() throws DispatcherException { |
96 |
|
|
97 | 14 |
Object result = null;
|
98 |
|
|
99 |
// get BPEL process and process context from process instance
|
|
100 | 14 |
ProcessContext ctx = instance.getContext(); |
101 | 14 |
BPELProcess process = instance.getProcess(); |
102 |
|
|
103 |
// check if a context was found or created
|
|
104 | 14 |
if (ctx == null) { |
105 | 4 |
throw new DispatcherException("No context found"); |
106 |
} |
|
107 |
|
|
108 |
// check if a process was found or created
|
|
109 | 10 |
if (process == null) { |
110 | 6 |
throw new DispatcherException("No process found"); |
111 |
} |
|
112 |
|
|
113 |
// start processing
|
|
114 | 4 |
start(); |
115 |
|
|
116 |
// if we have a synchronous process, wait until result is available
|
|
117 | 4 |
if (process.isSynchronous()) {
|
118 | 2 |
synchronized (ctx) {
|
119 | 2 |
try {
|
120 |
// wait until the process has finished and get the result
|
|
121 | 2 |
ctx.wait(); |
122 | 2 |
result = ctx.getResult(); |
123 |
} catch (InterruptedException e) {
|
|
124 | 0 |
throw new DispatcherException("Dispatcher interrupted", e); |
125 |
} |
|
126 |
} |
|
127 |
} else {
|
|
128 |
// TODO do we need to give something back here?
|
|
129 | 2 |
result = ASYNC_RESULT; |
130 |
} |
|
131 |
|
|
132 | 4 |
return result;
|
133 |
} |
|
134 |
|
|
135 |
/**
|
|
136 |
* Do not use this method directly. Use {@link #dispatch()}instead.
|
|
137 |
*/
|
|
138 | 0 |
public void run() { |
139 | 0 |
controller.processMessage(instance, message); |
140 |
} |
|
141 |
|
|
142 |
/**
|
|
143 |
* Gets the <code>ProcessContext</code> belonging to the incoming message.
|
|
144 |
*
|
|
145 |
* @param message
|
|
146 |
* the incoming message
|
|
147 |
* @return a new <code>ProcessContext</code> if there is currently no
|
|
148 |
* process running or the <code>ProcessContext</code> instance
|
|
149 |
* belonging to the incoming message if there is a process running
|
|
150 |
* already.
|
|
151 |
*/
|
|
152 | 6 |
protected ProcessContext getProcessContext(BexeeMessage message) {
|
153 |
|
|
154 | 6 |
ProcessContext ctx = null;
|
155 |
|
|
156 |
/*
|
|
157 |
* TODO Correlation stuff for finding a running process context. Right
|
|
158 |
* now this isn't supported, so we create a new instance each time.
|
|
159 |
*/
|
|
160 | 6 |
ctx = new ProcessContext();
|
161 |
|
|
162 | 6 |
return ctx;
|
163 |
} |
|
164 |
|
|
165 |
/**
|
|
166 |
* Gets the <code>BPELProcess</code> belonging to the incoming message.
|
|
167 |
*
|
|
168 |
* @param message
|
|
169 |
* the incoming message
|
|
170 |
* @return the <code>BPELProcess</code> that will be identified by the
|
|
171 |
* incoming message or null if it can't be found.
|
|
172 |
*/
|
|
173 | 6 |
protected BPELProcess getBPELProcess(BexeeMessage message) {
|
174 |
|
|
175 | 6 |
BPELProcess process = null;
|
176 | 6 |
String name = message.getService(); |
177 |
|
|
178 | 6 |
DAOFactory factory = DAOFactory.getInstance(); |
179 | 6 |
BPELProcessDAO bpelDAO = factory.createBPELProcessDAO(); |
180 |
|
|
181 | 6 |
try {
|
182 | 6 |
process = bpelDAO.find(name); |
183 |
} catch (DAOException e) {
|
|
184 | 0 |
log.info("Error trying to find process", e);
|
185 |
} |
|
186 |
|
|
187 | 6 |
return process;
|
188 |
} |
|
189 |
} |
|